package com.tanhua.dubbo.api.impl.mongo;


import com.tanhua.domain.mongo.*;
import com.tanhua.domain.vo.PageResult;
import com.tanhua.dubbo.api.mongo.PublishApi;
import com.tanhua.dubbo.utils.IdService;
import org.apache.dubbo.config.annotation.Service;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

@Service(timeout = 500000)
public class PublishApiImpl implements PublishApi {

    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private IdService idService;


    @Override
    public void save(Publish publish) {
        //1. 往动态表存入发布的动态数据  quanzi_publish
        //1.0 设置动态的pid，就是自增长id，主要是给推荐系统推荐计算的作用
        publish.setPid(idService.getNextId("quanzi_publish"));
        //1.1 设置动态id(mongo表的主键)
        //publish.setId(ObjectId.get());
        //1.2 保存
        mongoTemplate.save(publish);

        //2. 往相册表存入发布的动态数据  quanzi_album_userId
        //2.1 创建相册对象，存储的是自己的动态数据
        Album album = new Album();
        album.setPublishId(publish.getId());
        album.setCreated(publish.getCreated());
        //2.2 保存动态到相册表
        mongoTemplate.save(album,"quanzi_album_"+publish.getUserId());

        //3. 往好友的时间线表存储发布的动态数据。时间线表：存储好友的动态 quanzi_time_line_好友id
        //3.1 查询好友: db.tanhua_users.find({userId:1})
        Query query = new Query(Criteria.where("userId").is(publish.getUserId()));
        List<Friend> friendList = mongoTemplate.find(query, Friend.class);
        //3.2 往好友的时间线表保存当前发布的动态
        if (!CollectionUtils.isEmpty(friendList)) {
            for (Friend friend : friendList) {
                // 好友id: 20、4、23、10
                Long friendId = friend.getFriendId();
                // 创建时间线对象
                TimeLine timeLine = new TimeLine();
                timeLine.setUserId(publish.getUserId());
                timeLine.setPublishId(publish.getId());
                timeLine.setCreated(publish.getCreated());
                // 往好友的时间线表存储当前登陆用户（userId=1）发布的动态
                mongoTemplate.save(timeLine,"quanzi_time_line_" + friendId);
            }
        }
    }

    @Override
    public PageResult findByTimeLine(Integer page, Integer pagesize, Long userId) {
        // 构造查询条件
        Query query = new Query();
        // 根据created时间降序排序
        query.with(Sort.by(Sort.Order.desc("created")));
        // 分页
        query.skip((page-1)*pagesize).limit(pagesize);
        // 查询: 当前页数据
        List<TimeLine> timeLineList =
                mongoTemplate.find(query, TimeLine.class, "quanzi_time_line_" + userId);
        // 查询: 统计
        long count = mongoTemplate.count(query, TimeLine.class, "quanzi_time_line_" + userId);

        // 因为要返回List<Publish>, 这样更符合接口规范返回的数据要求，所以这里需要转换
        List<Publish> publishList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(timeLineList)) {
            for (TimeLine timeLine : timeLineList) {
                if (timeLine.getPublishId() != null) {
                    // 根据动态id查询动态
                    Publish publish =
                            mongoTemplate.findById(timeLine.getPublishId(), Publish.class);
                    if (publish != null) {
                        if (publish.getState() != null && publish.getState() == 1) {
                            // 添加到集合
                            publishList.add(publish);
                        }
                    }
                }
            }
        }
        return new PageResult(page,pagesize, (int) count,publishList);
    }

    @Override
    public PageResult queryRecommendPublishList(Integer page, Integer pagesize, Long userId) {
        //db.recommend_quanzi.find({userId:1}).sort({created:-1})
        // 构造查询条件
        Query query = new Query(
                Criteria.where("userId").is(userId)
        );
        // 根据created时间降序排序
        query.with(Sort.by(Sort.Order.desc("created")));
        // 分页
        query.skip((page-1)*pagesize).limit(pagesize);

        // 查询: 当前页数据
        List<RecommendQuanzi> list =
                mongoTemplate.find(query, RecommendQuanzi.class);
        // 查询: 统计
        long count = mongoTemplate.count(query, RecommendQuanzi.class);

        List<Publish> publishList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            for (RecommendQuanzi recommendQuanzi : list) {
                if (recommendQuanzi.getPublishId() != null) {
                    // 根据动态id查询动态
                    Publish publish =
                            mongoTemplate.findById(recommendQuanzi.getPublishId(), Publish.class);
                    // 添加条件判断：必须审核后的动态才可以显示
                    if (publish != null) {
                        if (publish.getState() != null && publish.getState() == 1) {
                            // 添加到集合
                            publishList.add(publish);
                        }
                    }
                }
            }
        }
        return new PageResult(page,pagesize, (int) count,publishList);
    }

    @Override
    public Publish findById(String publishId) {
        return mongoTemplate.findById(new ObjectId(publishId), Publish.class);
    }

    @Override
    public PageResult findByAlbum(Long userId, int page, int pagesize) {
        Query query = new Query()
                .limit(pagesize).skip((page-1)*pagesize)
                .with(Sort.by(Sort.Order.desc("created")));
        List<Album> albumList =
                mongoTemplate.find(query, Album.class, "quanzi_album_" + userId);
        long count = mongoTemplate.count(query, Album.class, "quanzi_album_" + userId);

        List<Publish> result = new ArrayList<>();
        if (albumList != null && albumList.size() > 0) {
            albumList.forEach(album -> {
                Publish publish =
                        mongoTemplate.findById(album.getPublishId(), Publish.class);
                if (publish!=null){
                    if (publish.getState() != null && publish.getState() == 1) {
                        result.add(publish);
                    }
                }
            });
        }
        return new PageResult(page,pagesize, (int) count,result);
    }

    @Override
    public PageResult findByPage(Integer page, Integer pagesize, Long uid, Integer state) {
        Query query=new Query();
        if(uid!=null){
             query = new Query(Criteria.where("userId").is(uid));
        }else{
             query = new Query();
        }

        if (state != null) {
            query.addCriteria(Criteria.where("state").is(state));
        }
        query.with(Sort.by(Sort.Order.desc("created")));
        query.skip((page-1)*pagesize).limit(pagesize);
        List<Publish> publishList = mongoTemplate.find(query, Publish.class);
        long count = mongoTemplate.count(query, Publish.class);
        return new PageResult(page,pagesize, (int) count,publishList);
    }

    @Override
    public void updateState(String id, Integer state) {
        // 更新条件：动态id
        Query query = new Query(Criteria.where("id").is(new ObjectId(id)));
        // 更新字段：state
        Update update = new Update();
        update.set("state",state);
        mongoTemplate.updateFirst(query,update,Publish.class);
    }

    @Override
    public List<Publish> findByPids(List<Long> pidList) {
        Query query = Query.query(
                Criteria.where("pid").in(pidList)
        );
        return mongoTemplate.find(query,Publish.class);
    }
    @Override
    public PageResult queryAlbumPublishList(Integer page, Integer pagesize, Long userId) {
        Query query=new Query();
        query.with(Sort.by(Sort.Order.desc("created")));
        query.skip((page-1)*pagesize).limit(pagesize);
        List<Album> albumList = mongoTemplate.find(query, Album.class, "quanzi_album_" + userId);
        List<Publish> publishList=new ArrayList<>();
        long count = mongoTemplate.count(query, Album.class, "quanzi_album_" + userId);
        if(albumList!=null){
            for (Album album : albumList) {
                ObjectId publishId = album.getPublishId();
                if(publishId!=null){
                    Publish publish = mongoTemplate.findById(publishId, Publish.class);
                    if(publish!=null){
                        publishList.add(publish);
                        if(publish.getSeeType()!=null&&publish.getState()==1) {
                            publishList.add(publish);
                        }
                    }
                }
            }
        }
        return new PageResult(page,pagesize,(int)count,publishList);

    }

    @Override
    public PageResult findByPublishList(Integer page, Integer pagesize, Long uid, String state) {
        if("1".equals(state)||"2".equals(state)||"0".equals(state)){
            Query query = new Query(Criteria.where("state").is(state));
            query.skip((page-1)*pagesize).skip(pagesize);
            List<Publish> publishList = mongoTemplate.find(query, Publish.class);
            long count = mongoTemplate.count(query, Publish.class);
            return new PageResult(page,pagesize,(int)count,publishList);
        }else{
            Query query = new Query();
            query.skip((page-1)*pagesize).skip(pagesize);
            List<Publish> publishList = mongoTemplate.find(query, Publish.class);
            long count = mongoTemplate.count(query, Publish.class);
            return new PageResult(page,pagesize,(int)count,publishList);
        }
    }

    @Override
    public void publishPass(String[] id) {
        for (String s : id) {
            Query query = new Query(Criteria.where("id").is(new ObjectId(s)));
            Update update = new Update();
            update.set("state",1);
            mongoTemplate.updateFirst(query,update,Publish.class);
        }
    }

    @Override
    public void publishUnPass(String[] id) {
        for (String s : id) {
            Query query = new Query(Criteria.where("id").is(new ObjectId(s)));
            Update update = new Update();
            update.set("state",2);
            mongoTemplate.updateFirst(query,update,Publish.class);
        }
    }
}
